
/**
 * 图片等高画廊
 * 
 * @todo 
 * 1. 等高展示，可设置图片目标高度 图片最大宽度/最小宽度;
 * 2. 分段加载，缓存，增加计算效率
 * 3. 可以自定义加载行数
 * 
 * @param {object} param
 * 字段说明
 * 
 * list         <Array>   图片数据, 必须包含 width/height 宽高信息
 * rowHeight    <Number>  图片目标高度
 * waperWidth   <Number>  容器宽度
 * gap          <Number>  间距, 默认 0
 * maxRow       <Int>     渲染行数 默认全部
 * threshold    <Number>  高度计算允许浮动范围 默认 20 
 * hideLast     <boolean> 放弃最后一行
 * 
 * ratioMax     <Number>  通过图片比例控制图片显示 最大比例
 * ratioMin     <Number>  通过图片比例控制图片显示 最小比例
 * maxWidth     <Number>  图片最大宽度
 * minWidth     <Number>  图片最小宽度
 * 
 */
function Gallery({
  list = [], 
  waperWidth, 
  rowHeight, 
  gap = 0,
  threshold = 20,
  maxRow,
  hideLast,
  ratioMax = 3,
  ratioMin = .5,
  maxWidth,
  minWidth,
}) {
  const H = rowHeight;
  const WW = waperWidth;

  if (!(list instanceof Array) || !WW || !H) return list;

  let newList = [];         // 生成的画廊
  let cacheRow = [];        // 当前行
  let currentRowWidth = 0;  // 当前行宽
  let nextRowWidth = 0;     // 下一行行宽
  let rowCount = 0;         // 记录行数

  // 统一图片高度
  list.forEach((v, i, arr) => {
    if (maxRow && rowCount >= maxRow) return;

    const currImg = nomalSize(v);
    const nextV = arr[i + 1];
    const nextImgWidth = nextV ? nomalSize(nextV)._width : 0;
    
    cacheRow.push(currImg);
    currentRowWidth += currImg._width;
    nextRowWidth = currentRowWidth + nextImgWidth;

    const rowlen = cacheRow.length;

    const currH = (WW - gap * rowlen) / currentRowWidth * H;
    const nextH = (WW - gap * (rowlen + 1)) / nextRowWidth * H;
  
    const currHF = currH - H;
    const nextHF = nextH - H;

    if (Math.abs(currHF) < threshold || Math.abs(currHF) < Math.abs(nextHF)) {
      // @todo 如果这行太小 需要适当调整图片尺寸 并重新计算
      // if (Math.abs(currHF) > threshold) 

      merge(currH);
    }

    if (i === (arr.length - 1) && rowlen && !hideLast) merge(H);

    return currImg;
  });

  function merge(imgh) {
    newList = newList.concat(cacheRow.map(v => {
      v._width = floor(imgh * v._ratio);
      v._height = floor(imgh);
      return v;
    }));

    cacheRow = [];
    currentRowWidth = 0;
    nextRowWidth = 0;
    rowCount++;
  }

  /**
   * 1. 计算图片目标尺寸
   * 2. 设置 最小/最大 宽度
   * 
   * @todo 浮动计算的可能
   * 
   * @param {Object} v image
   * @returns v
   */
  function nomalSize(v) {
    if (!v) return v;
    let ratio = v.width / v.height || 1;

    if (ratioMax && ratio > ratioMax) ratio = ratioMax;
    if (ratioMin && ratio < ratioMin) ratio = ratioMin;
  
    v._height = H;
    v._width = H * ratio;
    v._ratio = ratio;
  
    return v;
  }

  return newList;
}

function floor(num) {
  return Math.floor(num * 100) / 100;
}